package com.gui.juc.future;

import cn.hutool.core.thread.ThreadFactoryBuilder;
import com.gui.utils.Sleeper;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

@Slf4j
public class CompletableFutureDemo1 {

    public static void main(String[] args) throws Exception {

        // testThenRun();
        // thenAccept();
        testException();

    }

    private static void testThenApply() throws Exception {
        ExecutorService threadPool = Executors.newFixedThreadPool(1);
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            log.debug("supplyAsync...");
            Sleeper.sleep(2);
            ;
            return "success";
        }).thenApply((result) -> {
            log.debug("thenApply..." + result);
            return "thenApply";
        });
        log.debug(future1.get());
        threadPool.shutdown();
        log.debug("程序结束");
    }


    private static void testThenRun() throws Exception {
        ExecutorService threadPool = Executors.newFixedThreadPool(1);
        CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
            log.debug("supplyAsync...");
            Sleeper.sleep(2);
            ;
            return "success";
        }).thenRun(() -> log.debug("thenRun..."));
        log.debug(String.valueOf(future.get()));
        threadPool.shutdown();
        log.debug("程序结束");
    }

    private static void thenAccept() throws Exception {
        ExecutorService threadPool = Executors.newFixedThreadPool(1);
        CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
            log.debug("supplyAsync...");
            Sleeper.sleep(2);
            ;
            return "success";
        }).thenAccept((result) -> {
            log.debug("thenAccept..." + result);
        });
        log.debug(String.valueOf(future.get()));
        threadPool.shutdown();
        log.debug("程序结束");
    }

    public static void testException(){
        ThreadFactory factory = ThreadFactoryBuilder.create().setNamePrefix("completable-future-task").build();
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                2,
                1000,
                TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(10),
                factory,
                new ThreadPoolExecutor.AbortPolicy());
        log.debug("任务开始执行");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            Sleeper.sleep(1);
            if (2 != 3) {
                throw new RuntimeException("程序异常");
            }
            log.debug("supplyAsync");
            return "supplyAsync";
        }, threadPool).thenApply(result -> {
            Sleeper.sleep(1);
            log.debug("thenApply...");
            return result + "thenApply";
        }).exceptionally(e -> {
            log.error("完蛋 发生异常了");
            return "error";
        });
        try {
            log.debug(future.get());
        }catch (Exception e) {
            log.error("error", e);
        }
        log.debug("任务执行结束...");
        threadPool.shutdown();
    }


}
